//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This is a sample for BCGControlBar Library Professional Edition
// Copyright (C) 1998-2016 BCGSoft Ltd.
// All rights reserved.
//
// This source code can be used, distributed or modified
// only under terms and conditions 
// of the accompanying license agreement.
//*******************************************************************************
//
// ChartRealTimeView.cpp : implementation file
//

#include "stdafx.h"
#include "bcgpchartexample.h"
#include "ChartRealTimeView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define ID_TIMER				1
#define MAX_POINTS_IN_RANGE		750
#define MIN_FREQUENCY			16
#define MIN_VAL					-15
#define MAX_VAL					15

/////////////////////////////////////////////////////////////////////////////
// CChartRealTimeView

IMPLEMENT_DYNCREATE(CChartRealTimeView, CBCGPChartExampleView)

CChartRealTimeView::CChartRealTimeView()
	: CBCGPChartExampleView(CChartRealTimeView::IDD)
{
	//{{AFX_DATA_INIT(CChartRealTimeView)
		m_nUpdateFr = 15;
	//}}AFX_DATA_INIT

	m_bIsRunning = FALSE;
}

CChartRealTimeView::~CChartRealTimeView()
{
}

void CChartRealTimeView::DoDataExchange(CDataExchange* pDX)
{
	CBCGPChartExampleView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChartRealTimeView)
	DDX_Control(pDX, IDC_CHART, m_wndChart);
	DDX_Control(pDX, IDC_STOP, m_wndStop);
	DDX_Control(pDX, IDC_START, m_wndStart);
	DDX_Control(pDX, IDC_UPDATE_FR, m_wndUpdateFr);
	DDX_Slider(pDX, IDC_UPDATE_FR, m_nUpdateFr);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChartRealTimeView, CBCGPChartExampleView)
	//{{AFX_MSG_MAP(CChartRealTimeView)
	ON_BN_CLICKED(IDC_START, OnStart)
	ON_BN_CLICKED(IDC_STOP, OnStop)
	ON_WM_TIMER()
	ON_WM_HSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChartRealTimeView diagnostics

#ifdef _DEBUG
void CChartRealTimeView::AssertValid() const
{
	CBCGPChartExampleView::AssertValid();
}

void CChartRealTimeView::Dump(CDumpContext& dc) const
{
	CBCGPChartExampleView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CChartRealTimeView message handlers

void CChartRealTimeView::OnInitialUpdate() 
{
	CBCGPChartExampleView::OnInitialUpdate();
	
	if (m_bIsReady)
	{
		return;
	}

	m_bIsReady = TRUE;

	m_wndStop.EnableWindow(FALSE);

	m_wndUpdateFr.SetRange(100, 500, TRUE);
	UpdateData(FALSE);

	CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
	ASSERT_VALID(pChart);

	pChart->SetChartType(BCGPChartColumn);
	pChart->SetLegendPosition(BCGPChartLayout::LP_NONE);
	pChart->SetThemeOpacity(40);

	CBCGPChartAxis* pXAxis = pChart->GetChartAxis(BCGP_CHART_X_PRIMARY_AXIS);
	ASSERT_VALID(pXAxis);

	pXAxis->m_axisLabelType = CBCGPChartAxis::ALT_LOW;
	pXAxis->m_majorTickMarkType = CBCGPChartAxis::TMT_NO_TICKS;

	CBCGPChartAxis* pYAxis = pChart->GetChartAxis(BCGP_CHART_Y_PRIMARY_AXIS);
	ASSERT_VALID(pYAxis);

	pYAxis->SetFixedDisplayRange(MIN_VAL, MAX_VAL, 1.);

	int nTotalPoints = 16000 / MAX_POINTS_IN_RANGE + 1;

	m_arValues.SetSize(nTotalPoints);

	pXAxis->SetFixedDisplayRange(1., nTotalPoints + 1);

	pYAxis->m_strAxisName = _T("dB");
	pYAxis->m_bDisplayAxisName = TRUE;

	CString strCategory;

	double dblArg = 0.;

	for (int i = 0; i < nTotalPoints; i++)
	{
		m_arValues[i] = cos(dblArg) * MAX_VAL;
		dblArg += .2;

		int nFrq = i * MAX_POINTS_IN_RANGE + MIN_FREQUENCY;

		if (nFrq < 1000)
		{
			strCategory.Format(_T("%d"), nFrq);

			if (i == 0)
			{
				strCategory += _T("Hz");
			}
		}
		else
		{
			strCategory.Format(_T("%.1f"), nFrq / 1000.);

			if (i == nTotalPoints - 1)
			{
				strCategory += _T("kHz");
			}
		}

		pChart->AddChartData(strCategory, m_arValues[i]);
	}

	CBCGPChartBarSeries* pSeries = DYNAMIC_DOWNCAST (CBCGPChartBarSeries, pChart->GetSeries(0));
	ASSERT_VALID(pSeries);

	pSeries->SetColumnDistancePercent(25);
}

void CChartRealTimeView::OnStart() 
{
	UpdateData();

	SetTimer(ID_TIMER, m_nUpdateFr, NULL);

	m_wndStart.EnableWindow(FALSE);
	m_wndStop.EnableWindow();

	m_bIsRunning = TRUE;
}

void CChartRealTimeView::OnStop() 
{
	KillTimer(ID_TIMER);

	m_wndStart.EnableWindow();
	m_wndStop.EnableWindow(FALSE);

	m_bIsRunning = FALSE;
}

void CChartRealTimeView::OnTimer(UINT_PTR nIDEvent)
{
	if (nIDEvent != ID_TIMER || !IsWindowVisible())
	{
		return;
	}

	CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
	ASSERT_VALID(pChart);

	for (int i = 0; i < (int)m_arValues.GetSize(); i++)
	{
		double dblVal = m_arValues[i];
		double dblDelta = Rand(-2., 2.);

		dblVal += dblDelta;
		dblVal = max(MIN_VAL, min(MAX_VAL, dblVal));

		m_arValues[i] = dblVal;

		pChart->SetChartData(dblVal, 0, i, CBCGPChartData::CI_Y);
	}
	
	pChart->SetDirty();
	pChart->Redraw();
}

void CChartRealTimeView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	CBCGPChartExampleView::OnHScroll(nSBCode, nPos, pScrollBar);

	if (pScrollBar != NULL && m_bIsRunning)
	{
		UpdateData();

		KillTimer(ID_TIMER);
		SetTimer(ID_TIMER, m_nUpdateFr, NULL);
	}
}
